from robot.api import logger
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

import time

from ..assistant import FwVariables
from ..exception.TestException import TestException
from ..exception.errorcode import ErrorCode
from ..common.ui.WaitPageLoad import *
import requests
from robot.libraries.BuiltIn import BuiltIn
from .VersionEnum import VersionEnum

v8_login_ele_info = {
    "user": "inputUserName",
    "user_loc": By.ID,
    "pwd": "inputPasswd",
    "pwd_loc": By.ID,
    "verify_code": "verificationCode",
    "verify_image_code": "imgVerifyCode",
    "verify_code_loc": By.ID,
    "login_btn": "btnLogin",
    "login_btn_loc": By.ID,
}

v9_login_ele_info = {
    "user": "loginUserCode",
    "user_loc": By.ID,
    "pwd": "loginPassword",
    "pwd_loc": By.ID,
    "verify_code": "verificationCode",
    "verify_image_code": "imgVerifyCode",
    "verify_code_loc": By.ID,
    "login_btn": "btn-login",
    "login_btn_loc": By.CLASS_NAME,
}

big_data_login_ele_info = {
    "user": "username",
    "user_loc": By.ID,
    "pwd": "password",
    "pwd_loc": By.ID,
    "login_btn": "whale-pages-portal-user-login-submitBtn",
    "login_btn_loc": By.CLASS_NAME,
}

fishx_login_ele_info = {
    "user": "username",
    "user_loc": By.ID,
    "pwd": "password",
    "pwd_loc": By.ID,
    "verify_code": "verificationCode",
    "verify_image_code": "imgVerifyCode",
    "verify_code_loc": By.ID,
    "login_btn": "ant-btn-primary",
    "login_btn_loc": By.CLASS_NAME,
}

zcm_login_ele_info = {
    "user": "edt_username",
    "user_loc": By.ID,
    "pwd": "edt_pwd",
    "pwd_loc": By.ID,
    "verify_code": "verificationCode",
    "verify_image_code": "imgVerifyCode",
    "verify_code_loc": By.ID,
    "login_btn": "loginBtn",
    "login_btn_loc": By.CLASS_NAME,
}

# TODO 调试用，后面需要删除
test_login_ele_info = {
    "user": "staffCode",
    "user_loc": By.ID,
    "pwd": "loginPwd",
    "pwd_loc": By.ID,
    "verify_code": "verificationCode",
    "verify_image_code": "imgVerifyCode",
    "verify_code_loc": By.ID,
    "login_btn": "button[type=submit]",
    "login_btn_loc": By.CSS_SELECTOR,
}
default_login_ele_info = v9_login_ele_info


def get_login_info(url=None, user=None, password=None) -> dict:
    url = url if url else FwVariables.get_url()
    user = user if user else FwVariables.get_env_user()
    pwd = password if password else FwVariables.get_env_pwd()
    return {'url': url, 'user': user, 'pwd': pwd}


def portal_login(browser: webdriver, url=None, user=None, password=None, version=None):
    login_ele_info = _get_self_define_login_ele_info()
    if login_ele_info is None:
        if not version:
            version = FwVariables.get_version()
        version = version.upper()
        versionEnum = VersionEnum.get_by_version(version)
        if versionEnum in [VersionEnum.V8, VersionEnum.V90E, VersionEnum.ZCM_TEST, VersionEnum.V81E, VersionEnum.V9B]:
            login_ele_info = v8_login_ele_info
        elif versionEnum == VersionEnum.V9:
            login_ele_info = v9_login_ele_info
        elif versionEnum == VersionEnum.BIG_DATA:
            login_ele_info = big_data_login_ele_info
        # TODO 调试用，要删除
        elif versionEnum == VersionEnum.TEST:
            login_ele_info = test_login_ele_info
        elif versionEnum == VersionEnum.FISHX:
            login_ele_info = fishx_login_ele_info
        elif versionEnum == VersionEnum.ZCM:
            login_ele_info = zcm_login_ele_info
        elif versionEnum == VersionEnum.V9T:
            login_ele_info = v9_login_ele_info
        else:
            raise TestException.by_error_code(ErrorCode.PORTAL_LOGIN_NOT_ELEMENT)

    url = url if url else FwVariables.get_url()
    user = user if user else FwVariables.get_env_user()
    pwd = password if password else FwVariables.get_env_pwd()
    logger.info("login url {url}, user {user}".format(url=url, user=user))
    logger.info(login_ele_info)
    # browser.get(url)
    time.sleep(3)
    WebDriverWait(browser, FwVariables.get_wait_time_out()).until(
        EC.visibility_of_element_located((login_ele_info["user_loc"], login_ele_info["user"]))).send_keys(user)
    WebDriverWait(browser, FwVariables.get_wait_time_out()).until(
        EC.visibility_of_element_located((login_ele_info["pwd_loc"], login_ele_info["pwd"]))).send_keys(pwd)
    # TODO 调试用，要删除，输验证码
    # time.sleep(10)
    if FwVariables.get_value("ENV", "is_verify_code"):
        cookie_value = _get_cookie_value(browser, "SESSION")
        cookie = {"SESSION": cookie_value}
        retry_time = 3
        for i in range(retry_time):
            try:
                result = requests.get(FwVariables.get_value("ENV", "verify_code_api"), cookies=cookie)
                WebDriverWait(browser, FwVariables.get_wait_time_out()).until(
                    EC.visibility_of_element_located(
                        (login_ele_info["verify_code_loc"], login_ele_info["verify_code"]))).send_keys(eval(result.text))
                break
            except Exception as e:
                logger.warn(traceback.format_exc())
                if i == retry_time - 1:
                    raise TestException.by_exception(e)
                WebDriverWait(browser, FwVariables.get_wait_time_out()).until(
                    EC.visibility_of_element_located(
                        (login_ele_info["login_btn_loc"], login_ele_info["verify_image_code"]))).click()
    time.sleep(1)
    with WaitPageLoad(browser):
        WebDriverWait(browser, FwVariables.get_wait_time_out()).until(
            EC.visibility_of_element_located((login_ele_info["login_btn_loc"], login_ele_info["login_btn"]))).click()


def _get_cookie_value(browser: webdriver, cookie_name):
    cookie_name = cookie_name
    i = 0
    while i < 3:
        try:
            cookie = browser.get_cookie(cookie_name)
        except Exception as e:
            i += 1
            logger.info("第{}次获取cookie为None".format(i))
            logger.debug(e)
            time.sleep(1.5)
            # cookies = ";".join([item["name"] + "=" + item["value"] for item in cookies])
        else:
            return cookie["value"]
    if i == 3:
        raise Exception("The cookie is not existed!")

def _get_self_define_login_ele_info() -> dict:
    user = FwVariables.get_value("PORTAL", 'login_user_ele')
    user_loc = FwVariables.get_value("PORTAL", 'login_user_locate_by')
    pwd = FwVariables.get_value("PORTAL", 'login_pwd_ele')
    pwd_loc = FwVariables.get_value("PORTAL", 'login_pwd_locate_by')
    login_btn = FwVariables.get_value("PORTAL", 'login_btn_ele')
    login_btn_loc = FwVariables.get_value("PORTAL", 'login_btn_locate_by')
    if (user or user_loc or pwd or pwd_loc or login_btn or login_btn_loc):
        return {
            "user": user if user is not None else default_login_ele_info['user'],
            "user_loc": user_loc if user_loc is not None else default_login_ele_info['user_loc'],
            "pwd": pwd if pwd is not None else default_login_ele_info['pwd'],
            "pwd_loc": pwd_loc if pwd_loc is not None else default_login_ele_info['pwd_loc'],
            "login_btn": login_btn if login_btn is not None else default_login_ele_info['login_btn'],
            "login_btn_loc": login_btn_loc if login_btn_loc is not None else default_login_ele_info['login_btn_loc']
        }
    else:
        return None


def _portal_wait_menu_loaded(browser: webdriver, timeout: int = None):
    # 等待菜单加载完成, 成功返回True, 失败返回False
    timeout = timeout or FwVariables.get_wait_time_out()
    script = "return portal.allMenu.length"
    end_time = time.time() + timeout
    while True:
        try:
            time.sleep(1)
            menu_len = browser.execute_script(script)
            logger.info(f"menu count is {menu_len}")
            return True
        except Exception as e:
            if "portal is not defined" in str(e):
                logger.error("Not the Portal version, you should not use this open menu function!")
                # return False  #临时适配, 查看未初始化portal的原因
            # 其它报错，再循环再尝试
        if time.time() > end_time:
            logger.warn(f"wait portal menu loading time out for {timeout}s")
            return False


def portal_open_menu(browser: webdriver, *menus):
    # 打开菜单，成功返回False,失败返回True
    if not _portal_wait_menu_loaded(browser):
        return False

    menu_string = "->".join(menus)
    script = r'''var arr = arguments[0].split('->');
var menu = null;
var parent = null;
var i;
for (i = 0; i < arr.length; i++) {
	menu = fish.find(portal.allMenu, function(data) {
		if (parent != null) {
		    if (data.parentId && parent.partyId) {
		        if (data.parentId === parent.partyId && data.partyName === arr[i]) {
                    parent = data;
                    return data;
			    }
		    }
		} else {
			if (data.partyName === arr[i]) {
				parent = data;
				return data;
			}
		}
		return null;
	});
}
if (menu) {
	portal.openMenu(menu.partyId, menu.url, menu.menuType, menu.partyName, {});
	return true;
} else {
	return false;
}'''
    try:
        result = browser.execute_script(script, menu_string)
        if result is False:
            logger.error(f"Can't find the menu {menu_string}")
        return result is True
    except Exception as e:
        logger.error(e)
    return False


def change_portal(browser: webdriver, portal_name):
    portal_menus = PageElement(browser, 'portalDropdown', Selector.ID)
    is_open = portal_menus._get_web_element(True).get_attribute('class')
    if is_open != 'open':
        # 移动鼠标看能不能出来菜单
        portal_menus.move_curse()
    is_open = portal_menus._get_web_element(True).get_attribute('class')
    if is_open != 'open':
        # 点击看能不能出来
        portal_menus.click()
    menu = PageElement(browser,
                       f'//ul[contains(@class,"portalMenu")]/li[contains(@class,"portal-menu__item")]/a[text()="{portal_name}"]',
                       Selector.XPATH)
    menu.click()
